package com.qinglei.recoup.system.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.qinglei.recoup.common.domain.CommonConstant;
import com.qinglei.recoup.common.domain.CommonRes;
import com.qinglei.recoup.common.exception.RecoupException;
import com.qinglei.recoup.common.exception.RedisConnectException;
import com.qinglei.recoup.common.service.FileService;
import com.qinglei.recoup.common.service.RedisService;
import com.qinglei.recoup.common.utils.JsonUtils;
import com.qinglei.recoup.system.domain.Building;
import com.qinglei.recoup.system.domain.Tenant;
import com.qinglei.recoup.system.domain.TenantThemeBO;
import com.qinglei.recoup.system.domain.User;
import com.qinglei.recoup.system.enums.RoleEnum;
import com.qinglei.recoup.system.pojo.*;
import com.qinglei.recoup.system.service.TenantService;
import com.qinglei.recoup.system.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.IOException;
import java.time.LocalTime;
import java.util.List;

/**
 * @author syp
 */
@Api(tags = "【2.0新增】机构相关控制器-石-已完成")
@RestController
@RequestMapping("/tenant")
@Slf4j
public class TenantController {

    @Resource
    private TenantService tenantService;

    @Autowired
    private UserService userService;

    @Autowired
    private RedisService redisService;

    @Resource
    private FileService fileService;

    @ApiOperation(value = "添加机构")
    @PostMapping
    public CommonRes<Object> add(@RequestBody @Valid AddTenantParam param) {
        try {
            tenantService.add(param);
        } catch (RecoupException | RedisConnectException e) {
            log.error("添加机构失败", e);
            return CommonRes.failed("添加机构失败");
        }
        return CommonRes.ok();
    }

    @ApiOperation(value = "修改机构信息")
    @PutMapping
    public CommonRes<Object> update(@RequestBody @Valid UpdateTenantParam param) {
        Tenant tenant = tenantService.getById(param.getId());
        if (tenant == null) {
            return CommonRes.failed("机构不存在");
        }

        Tenant tenantUpdate = new Tenant();
        tenantUpdate.setId(tenant.getId());
        tenantUpdate.setName(param.getName());
        tenantUpdate.setSiteUrl(param.getSiteUrl());
        boolean res = tenantService.updateById(tenantUpdate);
        if (!res) {
            return CommonRes.failed("修改机构失败");
        }
        return CommonRes.ok();
    }

    @ApiOperation(value = "添加机构管理员")
    @PostMapping("/admin")
    public CommonRes<Long> addAdmin(@RequestBody @Valid AddTenantAdminParam param) throws RedisConnectException {
        Tenant tenant = tenantService.getById(param.getTenantId());
        if (tenant == null) {
            return CommonRes.failed("机构不存在");
        }
        if (tenant.getAdminUserId() != 0) {
            return CommonRes.failed("机构管理员不可重复添加");
        }

        String lockKey = CommonConstant.USER_ADD_LOCK_PREFIX + param.getMobile();
        Long setnx = redisService.setnx(lockKey, param.getMobile());
        if (setnx == 0) {
            return CommonRes.failed("请勿重复添加账号");
        }
        try {
            redisService.expire(lockKey, CommonConstant.USER_ADD_LOCK_TIMEOUT);
            User user = new User();
            BeanUtils.copyProperties(param, user);
            user.setTenantId(param.getTenantId());
            user.setRoleId(String.valueOf(RoleEnum.ADMIN.getCode()));
            this.userService.createUser(user);
            Tenant tenantUpdate = new Tenant();
            tenantUpdate.setId(tenant.getId());
            tenantUpdate.setAdminUserId(user.getId());
            tenantService.updateById(tenantUpdate);
            return CommonRes.ok(user.getId());
        } catch (RecoupException re) {
            log.error("addAdmin error", re);
            return CommonRes.failed(re.getMessage());
        }
        catch (Exception e) {
            log.error("addAdmin error", e);
        } finally {
            redisService.del(lockKey);
        }
        return CommonRes.failed("添加机构管理员失败");
    }

    @ApiOperation(value = "修改机构管理员")
    @PutMapping("/admin")
    public CommonRes<Object> updateAdmin(@RequestBody @Valid UpdateTenantAdminParam param) {
        try {
            User user = new User();
            BeanUtils.copyProperties(param, user);
            user.setId(param.getUserId());
            this.userService.updateUser(user);
            return CommonRes.ok("修改机构管理员成功");
        } catch (Exception e) {
            log.error("修改机构管理员失败", e);
        }
        return CommonRes.failed("修改机构管理员失败");
    }

    @ApiOperation(value = "修改机构主题")
    @PutMapping("/theme")
    public CommonRes<Object> updateTheme(@RequestBody @Valid UpdateTenantThemeParam param) {
        Tenant tenant = tenantService.getById(param.getTenantId());
        if (tenant == null) {
            return CommonRes.failed("机构不存在");
        }
        TenantThemeBO tenantThemeBO = new TenantThemeBO(param.getBannerUrl(), param.getBannerColor());
        Tenant tenantUpdate = new Tenant();
        tenantUpdate.setId(tenant.getId());
        tenantUpdate.setTheme(JsonUtils.objectToJson(tenantThemeBO));
        boolean res = tenantService.updateById(tenantUpdate);
        if (!res) {
            return CommonRes.failed("修改机构主题失败");
        }
        return CommonRes.ok();
    }

    @ApiOperation(value = "分页列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "机构名称 左前缀模糊匹配", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "pageNum", value = "当前页码，从1开始，默认是1", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "每页条数，默认20", paramType = "query", dataType = "Integer")
    })
    @GetMapping
    public CommonRes<IPage<TenantDetailVO>> getPageList(TenantSearchParam searchParam, PageParam pageParam) {
        IPage<TenantDetailVO> pageList = tenantService.getPageList(searchParam, pageParam);
        return CommonRes.ok(pageList);
    }

    @ApiOperation(value = "上传图片")
    @ApiImplicitParam(name = "file", value = "文件", paramType = "body", dataType = "file")
    @PostMapping("/uploadImg")
    public CommonRes<String> uploadImg(@RequestParam("file") MultipartFile file) throws IOException, RecoupException {
        String url = fileService.uploadImage(file);
        return CommonRes.ok(url, null);
    }

    @ApiOperation(value = "修改机构状态")
    @PutMapping("/status")
    public CommonRes<Object> updateStatus(@RequestBody @Valid UpdateTenantStatusParam param) {
        Tenant tenant = tenantService.getById(param.getTenantId());
        if (tenant == null) {
            return CommonRes.failed("机构不存在");
        }
        if (tenant.getStatus().equals(param.getStatus())) {
            return CommonRes.ok();
        }
        Tenant tenantUpdate = new Tenant();
        tenantUpdate.setId(tenant.getId());
        tenantUpdate.setStatus(param.getStatus());
        boolean res = tenantService.updateById(tenantUpdate);
        if (!res) {
            return CommonRes.failed("修改机构状态失败");
        }
        return CommonRes.ok();
    }

    @ApiOperation(value = "管理员 获取监测仪工作情况")
    @GetMapping("/monitorStatus")
    public CommonRes<TenantAssetVO> getMonitorStatus() {
        TenantAssetVO tenantAssetInfo = tenantService.getTenantAssetInfo();
        return CommonRes.ok(tenantAssetInfo);
    }
}